﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FySystem.Job.JobTask
{
    /// <summary>
    /// 新版定时任务基类，老版的定时任务都是直接继承了IJobTask
    /// </summary>
    public class JobBase
    {
        internal FyJobContext.FyJobAction JobExecuter;          //需要定时执行的委托

        /// <summary>
        /// 定时任务名称
        /// </summary>
        public string JobName { get; set; }
        /// <summary>
        /// 任务执行条件
        /// </summary>
        /// <param name="customJob"></param>
        /// <returns></returns>
        public delegate bool JudgeExecuteHandler(JobBase customJob);
        /// <summary>
        /// 每50ms由FyJobContext调用，判断是否触发执行
        /// </summary>
        public JudgeExecuteHandler ExecuteTrigger { get; protected set; }
        /// <summary>
        /// 下次执行时间
        /// </summary>
        /// <param name="customJob"></param>
        /// <returns></returns>
        public delegate DateTime NextExecuteTimeHandler(JobBase customJob);
        /// <summary>
        /// 用于生成下次的执行时间，只有当本次需要执行时，FyJobContext才会调用它来获取下次执行时间，
        /// 所以在写ExecuteTrigger的时候要注意第一次执行时如果返回false（不执行），则需要确保将NextExecuteTime设为非空
        /// </summary>
        public NextExecuteTimeHandler NextExecuteTimeGenerator { get; protected set; }

        /// <summary>
        /// 定时任务开始执行时间，默认是现在
        /// </summary>
        public DateTime StartTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 定时任务执行结束时间，超过这个时间后任务不会再执行，默认为时间的最大值
        /// </summary>
        public DateTime EndTime { get; set; } = DateTime.MaxValue;

        /// <summary>
        /// 下一次执行时间，默认为空
        /// </summary>
        public DateTime? NextExecuteTime { get; internal set; }

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="jobExecuter"></param>
        /// <param name="executeTrigger"></param>
        /// <param name="nextExecuteTimeGenerator"></param>
        public JobBase(string jobName, FyJobContext.FyJobAction jobExecuter)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(jobName))
                    throw new Exception("传入任务名称为空~");
                if (jobExecuter == null)
                    throw new Exception("传入执行函数为空~");

                JobName = jobName;
                JobExecuter = jobExecuter;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 内部调用，用于判断是否需要执行指定的任务
        /// </summary>
        /// <returns></returns>
        internal bool ExecuteJudge()
        {
            try
            {
                return ExecuteTrigger == null ? false : ExecuteTrigger.Invoke(this);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 内部调用，获取下次执行时间
        /// </summary>
        /// <returns></returns>
        internal DateTime GetNextExecuteTime()
        {
            try
            {
                return NextExecuteTimeGenerator == null ? DateTime.MaxValue : NextExecuteTimeGenerator.Invoke(this);
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
